In [1]:
import pandas as pd
coverage = pd.read_csv("../dataset/jacoco_production_coverage_spring_petclinic.csv")
coverage.head()
Out[1]:
In [2]:
coverage['lines'] = coverage.LINE_MISSED + coverage.LINE_COVERED
coverage['covered'] = coverage.LINE_COVERED / coverage.lines
coverage.head()
Out[2]:
In [3]:
%matplotlib inline
import matplotlib.pyplot as plt
ax = coverage.covered.hist();
ax.set_title("Verteilung der Gesamtausnutzung")
ax.set_xlabel("Anzahl")
ax.set_ylabel("Nutzungsgrad");
In [4]:
coverage['fqn'] = coverage.PACKAGE + "." + coverage.CLASS
coverage_per_class = coverage.set_index('fqn')[['lines', 'covered']]
coverage_per_class.head()
Out[4]:
In [5]:
# in C:\dev\repos\software-analytics\demos\dataset
# python -m "http.server" 28080
#URL = "http://localhost:28080/sonarqube_search.json"
In [6]:
#import json
#
#issues_json = ""
#
#with open ("../dataset/sonarqube_search.json") as f:
# issues_json = json.loads(f.read())
#
#json.dumps(issues_json)[:200]
In [7]:
import requests
KEY = "org.springframework.samples:spring-petclinic:boundedcontexts"
URL = "https://sonarcloud.io/api/issues/search?languages=java&componentKeys=" + KEY
issues_json = requests.get(URL).json()
print(str(issues_json)[:500])
In [8]:
from pandas.io.json import json_normalize
issues = json_normalize(issues_json['issues'])[['component', 'debt']]
issues['debt'] = issues.debt.apply(pd.Timedelta)
issues.head()
Out[8]:
In [9]:
issues['fqn'] = issues.component.str.extract("/java/(.*).java", expand=True)
issues['fqn'] = issues.fqn.str.replace("/", ".")
debt_per_class = issues.groupby('fqn')[['debt']].sum()
debt_per_class.head()
Out[9]:
In [10]:
analysis = coverage_per_class.join(debt_per_class)
analysis = analysis.fillna(0)
analysis.head()
Out[10]:
In [11]:
analysis['domain'] = "Other"
domains = ["Owner", "Pet", "Visit", "Vet", "Specialty", "Clinic"]
for domain in domains:
analysis.loc[analysis.index.str.contains(domain), 'domain'] = domain
analysis.groupby('domain')[['covered']].mean()
Out[11]:
In [12]:
management_compatible_data = analysis.\
groupby('domain').\
agg({"covered": "mean", "debt" : "sum", "lines" : "sum"})
management_compatible_data.debt = management_compatible_data.debt.dt.seconds / 60
management_compatible_data.columns = \
['Nutzungsgrad (%)', 'Technische Schulden (min)', 'Größe']
management_compatible_data.head()
Out[12]:
In [13]:
%matplotlib inline
from ausi import portfolio
portfolio.plot_diagram(management_compatible_data, "Technische Schulden (min)", "Nutzungsgrad (%)", "Größe", "fachliche Komponenten");
Erkenntnisse
Maßnahme: Für die Komponente "Other" müssen dringends qualitätsverbessernde Maßnahmen ergriffen werden
In [14]:
analysis['tech'] = analysis.index.str.split(".").str[-2]
analysis.groupby('tech')[['covered']].mean()
Out[14]:
In [15]:
management_compatible_data = analysis.groupby('tech').agg({"covered": "mean", "debt" : "sum", "lines" : "sum"})
management_compatible_data.debt = management_compatible_data.debt.dt.seconds / 60
management_compatible_data.columns = ['Nutzungsgrad (%)', 'Technische Schulden (min)', 'Größe']
portfolio.plot_diagram(management_compatible_data, "Technische Schulden (min)", "Nutzungsgrad (%)", "Größe", "technische Komponenten");